//
//  NSStringWrapper.m
//  NSStringWrapper
//
//  Created by Tang Qiao on 12-2-4.
//  Copyright (c) 2012年 blog.devtang.com. All rights reserved.
//
#import "NSString+Wrapper.h"
#import <CommonCrypto/CommonDigest.h>

@implementation NSString (Wrapper)
#define JavaNotFound -1

/**  Java-like method. Returns the char value at the specified index. */
- (unichar)charAt:(int)index {
    return [self characterAtIndex:index];
}

/**
* Java-like method. Compares two strings lexicographically.
* the value 0 if the argument string is equal to this string;
* a value less than 0 if this string is lexicographically less than the string argument;
* and a value greater than 0 if this string is lexicographically greater than the string argument.
*/
- (int)compareTo:(NSString *)anotherString {
    return [self compare:anotherString];
}

/** Java-like method. Compares two strings lexicographically, ignoring case differences. */
- (int)compareToIgnoreCase:(NSString *)str {
    return [self compare:str options:NSCaseInsensitiveSearch];
}

/** Java-like method. Returns true if and only if this string contains the specified sequence of char values. */
- (BOOL)contains:(NSString *)str {
    NSRange range = [self rangeOfString:str];
    return (range.location != NSNotFound);
}

- (BOOL)startsWith:(NSString *)prefix {
    return [self hasPrefix:prefix];
}

- (BOOL)endsWith:(NSString *)suffix {
    return [self hasSuffix:suffix];
}

- (BOOL)equals:(NSString *)anotherString {
    return [self isEqualToString:anotherString];
}

- (BOOL)equalsIgnoreCase:(NSString *)anotherString {
    return [[self toLowerCase] equals:[anotherString toLowerCase]];
}

- (int)indexOfChar:(unichar)ch {
    return [self indexOfChar:ch fromIndex:0];
}

- (int)indexOfChar:(unichar)ch fromIndex:(int)index {
    int len = self.length;
    for (int i = index; i < len; ++i) {
        if (ch == [self charAt:i]) {
            return i;
        }
    }
    return JavaNotFound;
}

- (int)indexOfString:(NSString *)str {
    NSRange range = [self rangeOfString:str];
    if (range.location == NSNotFound) {
        return JavaNotFound;
    }
    return range.location;
}

- (int)indexOfString:(NSString *)str fromIndex:(int)index {
    NSRange fromRange = NSMakeRange(index, self.length - index);
    NSRange range = [self rangeOfString:str options:NSLiteralSearch range:fromRange];
    if (range.location == NSNotFound) {
        return JavaNotFound;
    }
    return range.location;
}

- (int)lastIndexOfChar:(unichar)ch {
    int len = self.length;
    for (int i = len - 1; i >= 0; --i) {
        if ([self charAt:i] == ch) {
            return i;
        }
    }
    return JavaNotFound;
}

- (int)lastIndexOfChar:(unichar)ch fromIndex:(int)index {
    int len = self.length;
    if (index >= len) {
        index = len - 1;
    }
    for (int i = index; i >= 0; --i) {
        if ([self charAt:i] == ch) {
            return index;
        }
    }
    return JavaNotFound;
}

- (int)lastIndexOfString:(NSString *)str {
    NSRange range = [self rangeOfString:str options:NSBackwardsSearch];
    if (range.location == NSNotFound) {
        return JavaNotFound;
    }
    return range.location;
}

- (int)lastIndexOfString:(NSString *)str fromIndex:(int)index {
    NSRange fromRange = NSMakeRange(0, index);
    NSRange range = [self rangeOfString:str options:NSBackwardsSearch range:fromRange];
    if (range.location == NSNotFound) {
        return JavaNotFound;
    }
    return range.location;
}

- (NSString *)substringFromIndex:(int)beginIndex toIndex:(int)endIndex {
    if (endIndex <= beginIndex) {
        return @"";
    }
    NSRange range = NSMakeRange(beginIndex, endIndex - beginIndex);
    return [self substringWithRange:range];
}

- (NSString *)toLowerCase {
    return [self lowercaseString];
}

- (NSString *)toUpperCase {
    return [self uppercaseString];
}

- (NSString *)trim {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)replaceAll:(NSString *)origin with:(NSString *)replacement {
    return [self stringByReplacingOccurrencesOfString:origin withString:replacement];
}

- (NSArray *)split:(NSString *)separator {
    return [self componentsSeparatedByString:separator];
}

+ (NSString *)uuid {
    CFUUIDRef pUuid = CFUUIDCreate(NULL);
    CFStringRef pString = CFUUIDCreateString(NULL, pUuid);
    CFRelease(pUuid);
    NSString *uuid = [NSString stringWithString:(__bridge NSString *) pString];
    CFRelease(pString);
    return uuid;
}

- (NSString *)trimWhitespace {
    return [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSUInteger)numberOfLines {
    return [self componentsSeparatedByString:@"\n"].count + 1;
}

static NSString *htmlEntities[] = {@"<", @">", @"&", @" ", @"\"", @"\""};
static NSString *htmlEscapes[] = {@"&lt;", @"&gt;", @"&amp;", @"&nbsp;", @"&quot;", @"&#39;"};

//+ (NSString *)URLEncodedString:(NSString *)string {
//    NSString *result = (NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
//            (__bridge CFStringRef) string,
//            NULL,
//            CFSTR("!*'();:@&=+$,/?%#[]"),
//            kCFStringEncodingUTF8);
//    return result;
//}
//
//+ (NSString *)URLDecodedString:(NSString *)string {
//    string = [string stringByReplacingOccurrencesOfString:@"+" withString:@" "];
//
//    return [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//}


+ (NSString *)HTMLEscapeString:(NSString *)string {
    NSMutableString *tmp = [NSMutableString stringWithString:string];

    for (int i = 0; i < sizeof(htmlEntities) / sizeof(htmlEntities[0]); i++) {
        [tmp replaceOccurrencesOfString:htmlEntities[i]
                             withString:htmlEscapes[i]
                                options:NSCaseInsensitiveSearch
                                  range:NSMakeRange(0, tmp.length)];
    }

    return tmp;
}

+ (NSString *)HTMLEntityString:(NSString *)string {
    NSMutableString *tmp = [NSMutableString stringWithString:string];

    for (int i = 0; i < sizeof(htmlEscapes) / sizeof(htmlEscapes[0]); i++) {
        [tmp replaceOccurrencesOfString:htmlEscapes[i]
                             withString:htmlEntities[i]
                                options:NSCaseInsensitiveSearch
                                  range:NSMakeRange(0, tmp.length)];
    }

    return tmp;
}

+ (NSString *)md5:(NSString *)str {
    const char *cStr = [str UTF8String];
    unsigned char result[16] = {0};
    CC_MD5(cStr, strlen(cStr), result);
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
    ];
}

static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

+ (NSData *)base64Decode:(NSString *)string {
    unsigned long ixtext, lentext;
    unsigned char ch, inbuf[4], outbuf[4];
    short i, ixinbuf;
    Boolean flignore, flendtext = false;
    const unsigned char *tempcstring;
    NSMutableData *theData;

    if (string == nil) {
        return [NSData data];
    }

    ixtext = 0;

    tempcstring = (const unsigned char *) [string UTF8String];

    lentext = [string length];

    theData = [NSMutableData dataWithCapacity:lentext];

    ixinbuf = 0;

    while (true) {
        if (ixtext >= lentext) {
            break;
        }

        ch = tempcstring[ixtext++];

        flignore = false;

        if ((ch >= 'A') && (ch <= 'Z')) {
            ch = ch - 'A';
        } else if ((ch >= 'a') && (ch <= 'z')) {
            ch = ch - 'a' + 26;
        } else if ((ch >= '0') && (ch <= '9')) {
            ch = ch - '0' + 52;
        } else if (ch == '+') {
            ch = 62;
        } else if (ch == '=') {
            flendtext = true;
        } else if (ch == '/') {
            ch = 63;
        } else {
            flignore = true;
        }

        if (!flignore) {
            short ctcharsinbuf = 3;
            Boolean flbreak = false;

            if (flendtext) {
                if (ixinbuf == 0) {
                    break;
                }

                if ((ixinbuf == 1) || (ixinbuf == 2)) {
                    ctcharsinbuf = 1;
                } else {
                    ctcharsinbuf = 2;
                }

                ixinbuf = 3;

                flbreak = true;
            }

            inbuf[ixinbuf++] = ch;

            if (ixinbuf == 4) {
                ixinbuf = 0;

                outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
                outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
                outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);

                for (i = 0; i < ctcharsinbuf; i++) {
                    [theData appendBytes:&outbuf[i] length:1];
                }
            }

            if (flbreak) {
                break;
            }
        }
    }

    return theData;
}

+ (NSString *)base64Encode:(NSData *)data {
    static char base64EncodingTable[64] = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
    };
    int length = [data length];
    unsigned long ixtext, lentext;
    long ctremaining;
    unsigned char input[3], output[4];
    short i, charsonline = 0, ctcopy;
    const unsigned char *raw;
    NSMutableString *result;

    lentext = [data length];
    if (lentext < 1)
        return @"";
    result = [NSMutableString stringWithCapacity:lentext];
    raw = [data bytes];
    ixtext = 0;

    while (true) {
        ctremaining = lentext - ixtext;
        if (ctremaining <= 0)
            break;
        for (i = 0; i < 3; i++) {
            unsigned long ix = ixtext + i;
            if (ix < lentext)
                input[i] = raw[ix];
            else
                input[i] = 0;
        }
        output[0] = (input[0] & 0xFC) >> 2;
        output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
        output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
        output[3] = input[2] & 0x3F;
        ctcopy = 4;
        switch (ctremaining) {
            case 1:
                ctcopy = 2;
                break;
            case 2:
                ctcopy = 3;
                break;
        }

        for (i = 0; i < ctcopy; i++)
            [result appendString:[NSString stringWithFormat:@"%c", base64EncodingTable[output[i]]]];

        for (i = ctcopy; i < 4; i++)
            [result appendString:@"="];

        ixtext += 3;
        charsonline += 4;

        if ((length > 0) && (charsonline >= length))
            charsonline = 0;
    }
    return result;
}

/**
* 随机得到6位数
*/
+ (int)random6Number {
    return (arc4random() % 100000) + 999999;
}

+ (NSString *)base64Encoding:(NSString *)str {
    if ([str length] == 0) return @"";
    NSData *t_data = [NSData dataWithBytes:[str UTF8String] length:strlen([str UTF8String])];
    char *characters = malloc((([t_data length] + 2) / 3) * 4);

    if (characters == NULL)
        return nil;
    NSUInteger length = 0;

    NSUInteger i = 0;
    while (i < [t_data length]) {
        char buffer[3] = {0, 0, 0};
        short bufferLength = 0;
        while (bufferLength < 3 && i < [t_data length])
            buffer[bufferLength++] = ((char *) [t_data bytes])[i++];
        //  Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
        characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
        characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
        if (bufferLength > 1)
            characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
        else characters[length++] = '=';
        if (bufferLength > 2)
            characters[length++] = encodingTable[buffer[2] & 0x3F];
        else characters[length++] = '=';
    }

    return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
}

+ (NSString *)stringWithPrice:(id)price {
    return [NSString stringWithPrice:price format:@"$%.2f"];;
}

+ (NSString *)stringWithPrice:(id)price format:(NSString *)foramt {
    id str = nil;
    if ([price isKindOfClass:[NSString class]] && NSNotFound != [price rangeOfString:@"$"].location) {
        str = price;
    }
    else {
        str = [NSString stringWithFormat:foramt, [price floatValue]];
    }

    return str;
}

+ (NSString *)stringFromAddress:(NSDictionary *)shippingAddress {
    NSString *addressLine1 = shippingAddress[@"Addressline1"];
    NSString *addressLine2 = shippingAddress[@"Addressline2"];

    if (addressLine2.length > 0) {
        addressLine1 = [NSString stringWithFormat:@"%@\n%@", addressLine1, addressLine2];
    }

    return [NSString stringWithFormat:@"%@\n%@\n%@, %@ %@\n%@",
                                      shippingAddress[@"Name"],
                                      addressLine1,
                                      shippingAddress[@"City"],
                                      shippingAddress[@"State"],
                                      shippingAddress[@"Zipcode"],
                                      [shippingAddress[@"PhoneNumber"] parenthesesPhonenumber]];
}

#pragma mark format time string

//收到的时间格式为：@"11/20/2012T15:59:13";
//转换成 @"11-20-2012 15:59:13";
+ (NSString *)strFomateTimeString:(NSString *)strTime {
    NSMutableString *str = [NSMutableString stringWithString:strTime];

    [str replacingOccurrencesOfString:@"T" withString:@" "];
    [str replacingOccurrencesOfString:@"/" withString:@"-"];
    return str;
}

+ (NSString *)formateDate:(NSString *)time isCutTime:(BOOL)bCutTime {
    //time = @"11/20/2012T15:59:13";

    NSDate *date = [NSString convertDateFromString:[NSString strFomateTimeString:time]];
    NSString *strRes = [NSString stringFromDate:date isCutTime:bCutTime];
    return strRes;

}

+ (NSDate *)convertDateFromString:(NSString *)uiDate {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MM-dd-yyyy HH:mm:ss"];
    return [formatter dateFromString:uiDate];
}

+ (NSString *)stringFromDate:(NSDate *)date isCutTime:(BOOL)bCutTim {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    if (bCutTim) {
        dateFormatter.dateFormat = @"hh:mm aa";
    }
    else {
        dateFormatter.dateStyle = (NSDateFormatterStyle) kCFDateFormatterLongStyle;
    }

    return [dateFormatter stringFromDate:date];
}

- (UIColor *)colorWithHexString {
    NSString *cString = [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];

    // String should be 6 or 8 characters
    if ([cString length] < 6) return nil;

    // strip 0X if it appears
    if ([cString hasPrefix:@"0X"]) cString = [cString substringFromIndex:2];
    if ([cString hasPrefix:@"#"]) cString = [cString substringFromIndex:1];
    if ([cString length] != 6) return nil;

    // Separate into r, g, b substrings
    NSRange range = {0, 2};
    NSString *rString = [cString substringWithRange:range];

    range.location = 2;
    NSString *gString = [cString substringWithRange:range];

    range.location = 4;
    NSString *bString = [cString substringWithRange:range];

    // Scan values
    unsigned int r = 0, g = 0, b = 0;
    if (rString.length > 0) {
        [[NSScanner scannerWithString:rString] scanHexInt:&r];
    }
    if (gString.length > 0) {
        [[NSScanner scannerWithString:gString] scanHexInt:&g];
    }
    if (bString.length > 0) {
        [[NSScanner scannerWithString:bString] scanHexInt:&b];
    }

    return [UIColor colorWithRed:((float) r / 255.0f)
                           green:((float) g / 255.0f)
                            blue:((float) b / 255.0f)
                           alpha:1.0f];
}

- (NSString *)HTMLEscapeString {
    return [NSString HTMLEscapeString:self];
}

- (NSString *)HTMLEntityString {
    return [NSString HTMLEntityString:self];
}

- (NSString *)imageNameTrim {
    if (0 == self.length) return self;

    NSMutableString *linkUrl = nil;
    if (self.class == NSMutableString.class) {
        linkUrl = (NSMutableString *) self;
    }
    else {
        linkUrl = [NSMutableString stringWithString:self];
    }

    [linkUrl replacingOccurrencesOfString:@"&" withString:@""];
    [linkUrl replacingOccurrencesOfString:@"  " withString:@" "];
    [linkUrl replacingOccurrencesOfString:@" " withString:@"-"];
    [linkUrl replacingOccurrencesOfString:@"'" withString:@""];
    [linkUrl replacingOccurrencesOfString:@"," withString:@""];

    return linkUrl;
}

- (NSString *)urlTrim {
    if (0 == self.length) return self;

    NSMutableString *linkUrl = nil;
    if (self.class == NSMutableString.class) {
        linkUrl = (NSMutableString *) self;
    }
    else {
        linkUrl = [NSMutableString stringWithString:self];
    }
    [linkUrl replacingOccurrencesOfString:@"%20" withString:@" "];
//    [linkUrl replacingOccurrencesOfString:@"+" withString:@" "];
    [linkUrl replacingOccurrencesOfString:@"%257C" withString:@"|"];
    [linkUrl replacingOccurrencesOfString:@"%257c" withString:@"|"];
    [linkUrl replacingOccurrencesOfString:@"%7C" withString:@"|"];
    [linkUrl replacingOccurrencesOfString:@"%7c" withString:@"|"];
    [linkUrl replacingOccurrencesOfString:@"freetext=" withString:@"q="];

    return linkUrl;
}

- (BOOL)isEmailAddress {

    NSString *emailRegex = @"^\\w+((\\-\\w+)|(\\.\\w+))*@[A-Za-z0-9]+((\\.|\\-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$";
    emailRegex = @"[a-zA-Z0-9_\\-\\.\\+]+@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];

    return [emailTest evaluateWithObject:self];

}

- (NSString *)xmlEncodeString {
    NSMutableString *result = [NSMutableString stringWithString:self];

    [result replaceOccurrencesOfString:@"&"
                            withString:@"&amp;"
                               options:NSLiteralSearch
                                 range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@"\"" withString:@"&quot;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@"'" withString:@"&#x27;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@">" withString:@"&gt;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@"<" withString:@"&lt;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];

    DEBUG_LOG(@"%@", result);

    return result;
}


+ (NSString *)parenthesesPhonenumber:(NSString *)string; {
    NSMutableString *phoneString = [NSMutableString stringWithString:string];
    [phoneString replaceOccurrencesOfString:@"-"
                                 withString:@""
                                    options:NSCaseInsensitiveSearch
                                      range:NSMakeRange(0, phoneString.length)];
    [phoneString replaceOccurrencesOfString:@"("
                                 withString:@""
                                    options:NSCaseInsensitiveSearch
                                      range:NSMakeRange(0, phoneString.length)];
    [phoneString replaceOccurrencesOfString:@")"
                                 withString:@""
                                    options:NSCaseInsensitiveSearch
                                      range:NSMakeRange(0, phoneString.length)];
    [phoneString replaceOccurrencesOfString:@" "
                                 withString:@""
                                    options:NSCaseInsensitiveSearch
                                      range:NSMakeRange(0, phoneString.length)];

    if (phoneString.length > 7 && phoneString.length < 11) {
        [phoneString insertString:@"-" atIndex:3];
        [phoneString insertString:@"-" atIndex:7];
    }
    if (phoneString.length == 7) {
        [phoneString insertString:@"-" atIndex:3];
    }

    return phoneString;
}

+ (NSString *)updatePhonenumberMode:(NSString *)text updateString:(NSString *)string forRange:(NSRange)range {
    text = [text stringByReplacingCharactersInRange:range withString:string];
    text = [text stringByReplacingOccurrencesOfString:@"-" withString:@""];
    NSMutableString *newString = [NSMutableString stringWithString:text];
    if (newString.length > 6) {
        [newString insertString:@"-" atIndex:3];
        [newString insertString:@"-" atIndex:7];
    }
    return newString;
}

- (NSString *)parenthesesPhonenumber {
    return [NSString parenthesesPhonenumber:self];
}

- (NSString *)dateStringFromTime {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MM/dd/yyyy'T'HH:mm:ss"];
    NSDate *date = [formatter dateFromString:self];
    [formatter setDateFormat:@"ccc LLL dd"];
    return [formatter stringFromDate:date];
}

- (NSString *)substringThatFitsFrame:(CGRect)frame withFont:(UIFont *)font {
    NSString *truncatedString = self;

    CGSize size = [truncatedString sizeWithFont:font constrainedToSize:CGSizeMake(frame.size.width, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];

    NSMutableArray *components = [[truncatedString componentsSeparatedByString:@" "] mutableCopy];

    while (frame.size.height <= size.height) {

        [components removeLastObject];

        truncatedString = [components componentsJoinedByString:@" "];

        size = [truncatedString sizeWithFont:font constrainedToSize:CGSizeMake(frame.size.width, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];

    }

    return truncatedString;
}

+ (UIColor *)colorForHex:(NSString *)hexColor {

    if (!hexColor) return [UIColor whiteColor];

    hexColor = [[hexColor stringByTrimmingCharactersInSet:
            [NSCharacterSet whitespaceAndNewlineCharacterSet]
    ] uppercaseString];

    if ([hexColor hasPrefix:@"#"]) {
        hexColor = [hexColor stringByReplacingOccurrencesOfString:@"#" withString:@""];
    }

    // String should be 6 or 7 characters if it includes '#'
    if ([hexColor length] < 6)
        return [UIColor blackColor];


    // if the value isn't 6 characters at this point return
    // the color black
    if ([hexColor length] != 6)
        return [UIColor blackColor];

    // Separate into r, g, b substrings
    NSRange range;
    range.location = 0;
    range.length = 2;

    NSString *rString = [hexColor substringWithRange:range];

    range.location = 2;
    NSString *gString = [hexColor substringWithRange:range];

    range.location = 4;
    NSString *bString = [hexColor substringWithRange:range];

    // Scan values
    unsigned int r = 0, g = 0, b = 0;
    if (rString.length > 0) {
        [[NSScanner scannerWithString:rString] scanHexInt:&r];
    }
    if (gString.length > 0) {
        [[NSScanner scannerWithString:gString] scanHexInt:&g];
    }
    if (bString.length > 0) {
        [[NSScanner scannerWithString:bString] scanHexInt:&b];
    }

    return [UIColor colorWithRed:((float) r / 255.0f)
                           green:((float) g / 255.0f)
                            blue:((float) b / 255.0f)
                           alpha:1.0f];

}

- (BOOL)isEqualToStringIgnoreCase:(NSString *)compareString {
    return [[self lowercaseString] isEqualToString:[compareString lowercaseString]];
}

- (NSString *)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font addEllipsis:(BOOL)ellipsis {
    CGSize size = [self sizeWithFont:font];

    if (size.width <= width || width <= 0 || nil == font) return self;

    NSString *ellipsisStr = @"...";

    CGFloat actualWidth = width, currentWidth;
    if (ellipsis) {
        actualWidth -= [ellipsisStr sizeWithFont:font].width;
    }

    if (actualWidth <= 0) {
        actualWidth = width;
        ellipsis = NO;
    }

    NSInteger left = 0, right = self.length, middle;
    while (left < right) {
        middle = (left + right) / 2;

        NSString *currentString = [self substringToIndex:middle];
        currentWidth = [currentString sizeWithFont:font].width;

        if (currentWidth > actualWidth) {
            right = middle - 1;
        } else if (currentWidth < actualWidth) {
            left = middle + 1;
        } else {
            left = middle;
            break;
        }
    }

    if (left > 0) {
        NSString *currentString = [self substringToIndex:left];
        currentWidth = [currentString sizeWithFont:font].width;
        if (currentWidth > actualWidth) {
            left--;
        }
    }

    return [NSString stringWithFormat:@"%@%@", [self substringToIndex:left], ellipsis ? ellipsisStr : @""];
}

+ (NSString *)uniqueDeviceID {
    UIDevice *device = [UIDevice currentDevice];

    NSString *uniqueDeviceID = nil;

    // For iOS 6 and up, we can use identifierForVendor
    if ([device respondsToSelector:@selector(identifierForVendor)]) {
        uniqueDeviceID = [device.identifierForVendor UUIDString];     //device.identifier;
    }
    else
        // For iOS 5.X and lower we have to create our own UUID... pulling from the UserDefaults if we created one previously
    {
        uniqueDeviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"uniqueDeviceID"];
        if (!uniqueDeviceID) {
            CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
            CFStringRef ref = CFUUIDCreateString(kCFAllocatorDefault, uuid);
            CFRelease(uuid);
            uniqueDeviceID = [NSString stringWithString:(__bridge NSString *) ref];
            CFRelease(ref);
            [[NSUserDefaults standardUserDefaults] setObject:uniqueDeviceID forKey:@"uniqueDeviceID"];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
    }

    return uniqueDeviceID;
}

+ (NSString *)UUIDString {
    CFUUIDRef pUuid = CFUUIDCreate(NULL);
    CFStringRef pString = CFUUIDCreateString(NULL, pUuid);
    CFRelease(pUuid);
    NSString *uuid = [NSString stringWithString:(__bridge NSString *) pString];
    CFRelease(pString);
    return uuid;
}

- (NSString *)URLStringAddPath:(NSString *)pathStr {
    NSString *tmpStr = [self componentsSeparatedByString:@"?"][0];
    NSURL *tmpUrl = [NSURL URLWithString:tmpStr];
    if ([pathStr hasPrefix:@"/"]) {
        tmpStr = [tmpUrl path];
    } else {
        tmpStr = [tmpUrl lastPathComponent];
    }
    tmpStr = [[tmpUrl absoluteString] stringByReplacingOccurrencesOfString:tmpStr withString:pathStr];
    return tmpStr;
}

- (BOOL)isMobileNumber {
    NSString *regex = @"^((13[0-9])|(147)|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
    /**
    * 手机号码
    * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
    * 联通：130,131,132,152,155,156,185,186
    * 电信：133,1349,153,180,189
    */
    NSString *MOBILE = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\\\d{8}$";
    /**
    10         * 中国移动：China Mobile
    11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
    12         */
    NSString *CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\\\d)\\\\d{7}$";
    /**
    15         * 中国联通：China Unicom
    16         * 130,131,132,152,155,156,185,186
    17         */
    NSString *CU = @"^1(3[0-2]|5[256]|8[56])\\\\d{8}$";
    /**
    20         * 中国电信：China Telecom
    21         * 133,1349,153,180,189
    22         */
    NSString *CT = @"^1((33|53|8[09])[0-9]|349)\\\\d{7}$";
    /**
    25         * 大陆地区固话及小灵通
    26         * 区号：010,020,021,022,023,024,025,027,028,029
    27         * 号码：七位或八位
    28         */
    // NSString * PHS = @"^0(10|2[0-5789]|\\\\d{3})\\\\d{7,8}$";

    NSPredicate *pregextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
//    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
//    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
//    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
//    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];

    return [pregextestmobile evaluateWithObject:self];
//    return ([regextestmobile evaluateWithObject:self]
//            || [regextestcm evaluateWithObject:self]
//            || [regextestct evaluateWithObject:self]
//            || [regextestcu evaluateWithObject:self]) ;
}
@end

@implementation NSMutableString (Encode)

- (void)replacingOccurrencesOfString:(NSString *)oldString
                          withString:
                                  (NSString *)newString {
    [self replaceOccurrencesOfString:oldString
                          withString:newString
                             options:NSCaseInsensitiveSearch
                               range:NSMakeRange(0, [self length])];

}

- (void)trimAfterschoolImageUrl {
    [self replacingOccurrencesOfString:@" & " withString:@"-"];
    [self replacingOccurrencesOfString:@"  " withString:@"-"];
    [self replacingOccurrencesOfString:@" " withString:@"-"];
}
@end
